#if !defined(ximera_gui_cegui_windowtemplate_hpp)
#define ximera_gui_cegui_windowtemplate_hpp

// -----------------------------------------------------------

#include <ximera/gui/iwindow.hpp>
#include <ximera/common/utils.hpp>
#include <ximera/gui/cegui/cegui.hpp>

#include <CEGUIWindow.h>
#include <CEGUIWindowManager.h>

#include <vector>
#include <algorithm>

namespace ximera { namespace gui { namespace cegui
{
    template <typename Base>
    class XIMERA_PLUGIN_API WindowTemplate : public Base
    {
    public:
        WindowTemplate(CEGUI::Window* ceguiWindow);
        virtual ~WindowTemplate();

        virtual Real left() const;
        virtual void left(Real value);

        virtual Real top() const;
        virtual void top(Real value);

        virtual Real width() const;
        virtual void width(Real value);

        virtual Real height() const;
        virtual void height(Real value);

        virtual math::Vector2 position() const;
        virtual void position(math::Vector2 const& value);
        virtual void position(Real left, Real top);

        virtual math::Vector2 size() const;
        virtual void size(math::Vector2 const& value);
        virtual void size(Real width, Real height);

        virtual String text() const;
        virtual void text(String const& value);

        virtual bool visible() const;
        virtual void visible(bool value);

        virtual bool enabled() const;
        virtual void enabled(bool value);

        virtual IWindow* parent() const;

        virtual UInt32 childCount() const;
        virtual IWindow* child(UInt32 index) const;

        virtual void addChild(IWindow* child);
        virtual void removeChild(IWindow* child);
        virtual void removeAllChildren();

        virtual bool isChild(IWindow* child);

        virtual void show();
        virtual void hide();

        virtual void bringToFront();
        virtual void sendToBack();

        virtual void beginUpdate();
        virtual void endUpdate();

        virtual SignalAccess<ClickEvent> onClick();
        virtual SignalAccess<MouseEnterEvent> onMouseEnter();
        virtual SignalAccess<MouseExitEvent> onMouseExit();
        virtual SignalAccess<MouseMoveEvent> onMouseMove();
        virtual SignalAccess<MouseDownEvent> onMouseDown();
        virtual SignalAccess<MouseUpEvent> onMouseUp();
        virtual SignalAccess<KeyDownEvent> onKeyDown();
        virtual SignalAccess<KeyUpEvent> onKeyUp();

        CEGUI::Window* ceguiWindow() const { return _ceguiWindow; }
        void parent(IWindow* window) { _parent = window; }

    protected:
        typedef WindowTemplate<Base> SelfType;
        typedef std::vector<IWindow*> ChildContainer;

        IWindow* _parent;
        ChildContainer _children;

        Signal<ClickEvent> _onClick;
        Signal<MouseEnterEvent> _onMouseEnter;
        Signal<MouseExitEvent> _onMouseExit;
        Signal<MouseMoveEvent> _onMouseMove;
        Signal<MouseDownEvent> _onMouseDown;
        Signal<MouseUpEvent> _onMouseUp;
        Signal<KeyDownEvent> _onKeyDown;
        Signal<KeyUpEvent> _onKeyUp;

        CEGUI::Window* _ceguiWindow;

        bool handleClick(CEGUI::EventArgs const& e);
        bool handleMouseEnter(CEGUI::EventArgs const& e);
        bool handleMouseExit(CEGUI::EventArgs const& e);
        bool handleMouseMove(CEGUI::EventArgs const& e);
        bool handleMouseDown(CEGUI::EventArgs const& e);
        bool handleMouseUp(CEGUI::EventArgs const& e);
        bool handleKeyDown(CEGUI::EventArgs const& e);
        bool handleKeyUp(CEGUI::EventArgs const& e);
    };
}}}

#include <ximera/gui/cegui/inline/windowtemplate.inl>

// -----------------------------------------------------------

#endif
